/*
 * Clase controladora del la vista salón
 */
package grest.controller;


import grest.model.*;
import grest.view.VistaBusqueda;
import java.awt.event.ActionListener;
import grest.view.VistaSalon;
import java.awt.event.ActionEvent;
import java.util.Observable;
import javax.swing.DefaultListModel;
import javax.swing.JList;
import javax.swing.JTable;
import javax.swing.JTextField;
import java.sql.*;
import java.util.ArrayList;
import java.util.Observer;
import javax.swing.JOptionPane;

/**
 *
 * @author Santiago, Agustín, Rodrigo
 */
public class CtrlrVistaSalon implements ActionListener,Observer {
    private VistaSalon form = null;
    private TableModelSL tableModel = null;
    private DefaultListModel listModel = null;
    private JTable tablaMesas;
    private ArrayList<Mozos> listaMozos = new ArrayList<Mozos>();
    private Integer nroPersonas;
    private Integer nroReserva;
    private int[] filasSelec;
    private ArrayList<Integer> mesasSelec;
    /**
     * Constructor de la clase
     * @param form 
     */
    public CtrlrVistaSalon(VistaSalon form){
        this.form = form;
        this.tablaMesas = (JTable) form.getControls("tablaMesas");
        tableModel = new TableModelSL(new Mesas());
        ((JTable) form.getControls("tablaMesas")).setModel(tableModel);
        //tableModel.addTableModelListener(tablaMesas);
        try{
            consultarEstadoMesas();
        }catch(SQLException e){
            JOptionPane.showMessageDialog(this.form,"No se pudo cargar información necesaria para el funcionamiento. Detalles:"+ e.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
        }
         listModel = new DefaultListModel();
        ((JList) form.getControls("lstListaMozos")).setModel(listModel);
        this.mesasSelec = new ArrayList<Integer>();
        //-----------------------------
    }
    
    @Override
    public void actionPerformed(ActionEvent e){
        if(e.getSource()==form.getControls("btnAbrir")){
            try{   
                this.getData();
                this.executeAltaMesas();                
            }catch(Exception ex){
                JOptionPane.showMessageDialog(this.form, ex.getMessage(), ex.getCause().getMessage(), JOptionPane.ERROR_MESSAGE);
            }  
        }
        else if(e.getSource()==form.getControls("btnAgregarMoz")){
            try{
                this.agregarMozo(Integer.parseInt(((JTextField) form.getControls("txtCodMoz")).getText()));
            }catch(NumberFormatException ex){
                JOptionPane.showMessageDialog(this.form, "Ingrese un valor válido","Error",JOptionPane.WARNING_MESSAGE);
            }
        }
        else if(e.getSource()==form.getControls("btnQuitarMoz")){
            try{
                listModel.removeElementAt(((JList)form.getControls("lstListaMozos")).getSelectedIndex());
            }catch(ArrayIndexOutOfBoundsException ex){
                
            }
        }
        else if(e.getSource()==form.getControls("btnCerrarMesa")){
            cerrarMesa();
        }else if(e.getSource()==form.getControls("btnRefrescar")){
            refresh((JTable)form.getControls("tablaPedidos"));
        }else if(e.getSource()==form.getControls("btnBorrarPed")){
            borrarPedidos();
        }else if(e.getSource()==form.getControls("btnBuscarMoz")){
            busquedaMozo();
        }
        else if(e.getSource()==form.getControls("btnBuscarReserv")){
            busquedaReserva();
        }
        
    }
    /**
     * Obtiene las mesas seleccionaadas
     */
    private ArrayList<Mesas> getMesasSelec() throws Exception{
         Integer i ;
         ArrayList<Mesas> m = new ArrayList<Mesas>();
         this.filasSelec= ((JTable)form.getControls("tablaMesas")).getSelectedRows();
         if(this.filasSelec.length==0) throw new Exception("Debe seleccionar al menos una mesa", new Throwable("No hay una mesa seleccionada"));
         for (i = 0 ; i < filasSelec.length ; i++){
            int row = filasSelec[i];
            this.mesasSelec.add(((Integer) tablaMesas.getValueAt(row, 0)));
            m.add((Mesas)tableModel.getModel().get(row));
         }  
         return m;
    }
    /**
     * Obtiene los datos de los componentes del panel contextual ABRIR_MESA
     */
    private void getData() throws Exception{
         Integer i ;
         listaMozos.clear();
         mesasSelec.clear();
         filasSelec=null;
         
         if(((JTextField) form.getControls("txtCantidadP")).getText().length()>0)
            this.nroPersonas = Integer.parseInt(((JTextField) form.getControls("txtCantidadP")).getText());
         else
             throw new Exception("Debe establecer la cantidad de comensales", new Throwable("No hay definida una cantidad de comensales"));
         //Verifico que exista una reserva, sino establezco su valor como null
         this.nroReserva = (((JTextField) form.getControls("txtNroReserv")).getText().length()>0) ?
                 Integer.parseInt(((JTextField) form.getControls("txtNroReserv")).getText()) : null;
         for (i = 0 ; i < listModel.getSize() ; i++){
            Object o = listModel.getElementAt(i);
            this.listaMozos.add((Mozos)o);
         }
         if(this.listaMozos.isEmpty()) throw new Exception("Debe seleccionar al menos un mozo", new Throwable("No hay mozos asignados"));
         getMesasSelec();
    }
    /**
     * Realia la ejecucion de los StoredProcedures correspondientes a la alta de mesas.
     */
    private void executeAltaMesas(){
        Integer aux=null;
        String p="P_ALTA_MOV_MESA";
            try{      
                Integer idMov=null;
                StoredProcedure altaTMovMesas = new StoredProcedure("P_ALTA_MOV_MESA", false);
                //Parámetros de altaMovMesas
                altaTMovMesas.addParamIn(this.nroPersonas);
                altaTMovMesas.addParamIn(this.nroReserva);
                altaTMovMesas.addParamOut(Types.INTEGER);
                idMov=(Integer)DataIO.executeEProcedure(altaTMovMesas).get(0);
                System.out.print(idMov);
                aux=idMov;
                DataIO.doCommit();
                p="P_ALTA_MESA_SERVICIO";
                //Parámetros de altaMesasServ
                for(Integer mesa : this.mesasSelec){
                   StoredProcedure altaTMesasServ = new StoredProcedure("P_ALTA_MESA_SERVICIO",false);
                   altaTMesasServ.addParamIn(idMov);
                   altaTMesasServ.addParamIn(mesa); 
                   DataIO.executeEProcedure(altaTMesasServ);
                }
                p="P_ALTA_ATENCION_MOZOS";
                for(Mozos m : listaMozos){
                   StoredProcedure altaTAtencionMozos = new StoredProcedure("P_ALTA_ATENCION_MOZOS", false);
                   altaTAtencionMozos.addParamIn(idMov);
                   altaTAtencionMozos.addParamIn(m.getNro());
                   DataIO.executeEProcedure(altaTAtencionMozos);
                }
                DataIO.doCommit();
                for(Entidad m : this.tableModel.getModel()){
                    if(this.mesasSelec.contains(((Mesas)m).getNroMesa())){
                        ((Mesas)m).setEstado(Mesas.OCUPADA);
                        ((Mesas)m).setChanged(false);
                        ((Mesas)m).setIdMovActual(idMov);
                    }
                }
                this.tableModel.fireTableDataChanged();
            }catch(SQLException e){
                JOptionPane.showMessageDialog(null, "Verificar Datos\n  -Verificar Numero de Reserva\n","Datos Incorrectos",JOptionPane.WARNING_MESSAGE);
                DataIO.executeQuery("DELETE FROM T_MOV_MESAS WHERE ID_MOVIMIENTO="+aux);
                DataIO.doCommit();
            }
    }
    
    private void agregarMozo(int id){
       try{
           String consulta = "select nro_mozo,apellido,nombre from t_mozos where nro_mozo = "+ id;
           ResultSet rs = DataIO.getResultSet(consulta);
           if ( rs != null ){                   
                try {
                    while ( rs.next() ) {
                        //String name = rs.getString("apellido") +","+ rs.getString("nombre");
                        //listModel.addElement(name);
                        Mozos m =new Mozos(rs.getInt(1), rs.getString(2), rs.getString(3));
                        Boolean f=false;
                        Integer i=0;
                        while(i<listModel.size() && !f){ 
                            f= ((Mozos)listModel.get(i)).getNro()==m.getNro();
                            i++;
                        }
                        
                        if(!f)listModel.addElement(m);

                    }
                } catch (SQLException sql) {
                    DataIO.doException(sql,"Error loading objects from ["+consulta+"]");
                }
           }
           else{
               System.out.print("El codigo de mozo no existe");
           }
       }catch(NumberFormatException e){
           JOptionPane.showMessageDialog(this.form, "Ingrese un valor válido","Error",JOptionPane.WARNING_MESSAGE);
       }
    }
    
    private void cerrarMesa(){
        try{
            ArrayList<Mesas> mesasS = getMesasSelec();
            if(mesasS.size()==1){
                Integer idMovACerrar= mesasS.get(0).getIdMovActual();
                StoredProcedure sp = new StoredProcedure("P_BAJA_MESA2", false);
                sp.addParamIn(idMovACerrar);
                for(Entidad m : this.tableModel.getModel()){
                    if(((Mesas)m).getIdMovActual()==idMovACerrar){
                        ((Mesas)m).setEstado(Mesas.LIBRE);
                        ((Mesas)m).setChanged(false);
                        ((Mesas)m).setIdMovActual(Mesas.SIN_MOV_MESA);
                    }
            }
            DataIO.executeEProcedure(sp);
            DataIO.doCommit();
            tableModel.fireTableDataChanged();
            }
        }catch(Exception e){
            JOptionPane.showMessageDialog(this.form, e.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
        }
    }
    /**
     * Consulta mesas que quedaron abiertas en una sesión previa del programa
     * @throws SQLException 
     */
    private void consultarEstadoMesas() throws SQLException{
        ResultSet mesasAbiertas = DataIO.getResultSet("SELECT NRO_MESA,ID_MOVIMIENTO FROM V_MESAS_ABIERTAS");
        while(mesasAbiertas.next()){
            Integer nroMesaAbierta=mesasAbiertas.getInt("NRO_MESA");
            for(Entidad e:tableModel.getModel()){
                if(((Mesas)e).getNroMesa()==nroMesaAbierta) ((Mesas)e).setIdMovActual(mesasAbiertas.getInt("ID_MOVIMIENTO"));
            }
        }
    }
    /**
     * Actualiza la tabla especificada de la vista salón
     * @param tabla 
     */
    public void refresh(JTable tabla){
        if(tabla.equals(tablaMesas)){
            tableModel = new TableModelABM(new Mesas());
            tabla.setModel(tableModel);        
            try{
                consultarEstadoMesas();
                tableModel.fireTableDataChanged();
            }catch(SQLException ex){
                JOptionPane.showMessageDialog(this.form,"No se pudo cargar información necesaria para el funcionamiento. Detalles:"+ ex.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
            }
        }else if(tabla.equals(form.getControls("tablaPedidos"))){
            try{
                ArrayList<Mesas> ms = getMesasSelec();
                tabla.setModel(new TableModelABM(new Pedido(ms.get(0).getIdMovActual())));
            }catch(Exception e){
                JOptionPane.showMessageDialog(this.form,"No se pudo cargar información necesaria para el funcionamiento. Detalles:"+ e.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
            } 
        }
    }
    
    private void borrarPedidos(){
        Integer r;
        ArrayList<Pedido> pedidosAborrar = new ArrayList<Pedido>();
        TableModelABM tModel=(TableModelABM)((JTable)form.getControls("tablaPedidos")).getModel();
        int rs[]=((JTable)form.getControls("tablaPedidos")).getSelectedRows();
        for(r=0;r<rs.length;r++){
            pedidosAborrar.add((Pedido)tModel.getModel().get(rs[r]));
        }
        for(Pedido p:pedidosAborrar){
                System.out.print(p.getDeleteQuery());
                DataIO.executeQuery(p.getDeleteQuery());
                if(DataIO.doCommit())tModel.getModel().remove(p);
        }
        tModel.fireTableDataChanged();
        
    }
    private void busquedaMozo(){
        VistaBusqueda vistaB = new VistaBusqueda(new Mozos(),this);
    }
    
    private void busquedaReserva(){
        Reservas r = new Reservas();
        VistaBusqueda d = new VistaBusqueda(r,this);
    }

    @Override
    public void update(Observable o, Object arg) {
        if (arg instanceof Mozos)
            this.listModel.addElement(arg);
        else if (arg instanceof Reservas)
            ((JTextField)(form.getControls("txtNroReserv"))).setText(String.valueOf(((Reservas) arg).getNroReserva()));
    }
}
